<?php

namespace App\Services\Stock;

use App\Models\Steel\SteelArchive;
use App\Models\Stock\Stock as StockStock;
use App\Models\Stock\StockField;
use App\Models\Stock\StockFieldRule;
use App\Models\Stock\StockSub;
use App\Models\Warehouse\WarehouseList;
use Illuminate\Support\Facades\Redis;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Http\Controllers\Order\SaleorderController;
use App\Models\Saleprice\Saleprice;

class Stock
{
    /**
     * 获取库存查询
     */
    public static function getList(Request $request, $cpid, $utype)
    {
        $isgetlist = $request->isgetlist ?? 0;
        if ($isgetlist == 0) {
            $field_rule = StockField::get();
            foreach ($field_rule as &$val) {
                $val['ischecked'] = 1;
            }
            $rule_info = new \StdClass();
            $rule_info->field_rule = json_encode($field_rule);
        } else {
            $rule_info = StockFieldRule::where(['cpid' => $cpid, 'utype' => $utype])->first();
            if (!$rule_info) {
                // $field_rule = StockField::get();
                // foreach ($field_rule as &$val) {
                //     $val['ischecked'] = 1;
                // }
                // $rule_info= new \StdClass();
                // $rule_info->field_rule=json_encode($field_rule);
                return ['code' => '500', 'msg' => '无权限'];
            }
        }

        $field_list = self::getFieldData($rule_info);
        // print_r($field_list);exit;
        $list = StockStock::getList($request, $cpid,$utype);
        // print_r($list);exit;

        $price_data=self::getsaleprice($cpid);
        if (isset($price_data['base']['基价'])) {
            $base_price = $price_data['base']['基价']['amount'];
        }else{
            $base_price=0;
        }
        foreach ($list['list'] as $key => &$val) {
            //根据材质查询价格

            $val['supply_base_price'] = $val['suppleyprice']['base_price'];
            // $val['supply_add_price'] = $val['suppleyprice']['add_price'];
            $val['supply_price'] = intval(bcadd($val['supply_base_price'], $val['supply_add_price']));

            // $val['custom_base_price'] = $val['customprice']['base_price'];
            // $val['custom_add_price'] = $val['customprice']['add_price'];
            // $val['custom_price'] = $val['customprice']['price'];

            $add_price=self::getsteelprice($price_data, 0, $val);

            $val['custom_base_price'] = $base_price;
            $val['custom_add_price'] = $add_price;
            $val['custom_price'] = $base_price+$add_price;

            $val['warehouse_name'] = $val['warehousename']['warehouse_name'];

            if(is_array($val['substock']))
            {
                foreach ($val['substock'] as $k1 => $v1)
                {
                    $val['substock'][$k1]['price'] = self::getsteelprice($price_data, $base_price, $v1);
                    $val['substock'][$k1]['total_money'] = mathfuncmoney('mul',mathfuncweight('div',$v1['total_weight'],1000,4),$v1['price'],0);
                }
            }

            unset($val['customprice']);
            unset($val['suppleyprice']);
            unset($val['warehousename']);
            unset($val['create_at']);
            unset($val['update_at']);
            unset($val['cpid']);
            unset($val['warehouse_id']);
            unset($val['steel_archive_id']);
            unset($val['material_id']);

            foreach ($field_list['not_checked_field_list'] as $v) {
                unset($val[$v]);
            }
        }
        $list['field_list'] = $field_list['field_list'];
        return $list;
    }

    protected static function getFieldData($rule_info)
    {
        $field_rule = json_decode($rule_info->field_rule, true);
        $field_list = [];
        $not_checked_field_list = [];
        foreach ($field_rule as $v) {
            if ($v['ischecked'] == 1) {
                $field_list[$v['field_name']] = $v['field_title'];

                // $field_list[]=[$v['field_name']=>$v['field_title']];
            } else {
                $not_checked_field_list[] = $v['field_name'];
            }
        }

        return ['field_list' => $field_list, 'not_checked_field_list' => $not_checked_field_list];
    }


    /**
     * 库存入库
     * 无库存则生成库存，无子库存则生成子库存
     * $status,1待入（采购订单传正数，结算传负数），2正式入库
     *
     *
     * 理记 钢材，确定的只有宽和高，长度需要输入 提交时，要有长度length （长（取库存的子级的长度）*宽*高/1000*0.00785）
     * 定尺 钢材，长宽高一开始就是确定的
     * 过磅 钢材，重量 件数
     *
     * 理计和定尺在订单处的单重=库存的可用重量/可用件数，重量=件数*单重，等出库时选了长度后才用公式
     * 有三级结构后才引入了长度，在用原来的公式校准订单，刚开始没出库，不知道仓库会发多少长度的，所以取得是个均值，
     * 出库的时候选择的那个三级结构，才相当于选择出具体的长度
     *
     * 在销售订单的时候，没有长度的概念，所以不用长度的公式计算单重，理计的单重的是库存里的库用重量/可用件数，
     * 重量是=单重*件数，过磅的重量是输入的，等有仓库返单后，做出库操作时选择的三级结构，才带入长度，用长度来计算，校准订单
     *
     *
     * 定尺/理记 钢材，只能输入件数,理记单重取平均值 定尺直接计算
     * 过磅/虚拟 钢材，总重/件数, 都是可输入. 根据测试确认的 2025.06.18
     *
     *
     *
     */
    public static function doStockIn($cpid, $stock_id, $count, $weight, $status = 1, $length = 0)
    {
        $stockinfo = StockStock::where(['cpid' => $cpid, 'id' => $stock_id])->first();
        if (!$stockinfo) {
            throw new \Exception('无效库存参数');
        }

        $updatedata = [];
        if ($status == 1) {
            $updatedata = [
                'storage_waiting_pieces' => DB::raw('storage_waiting_pieces + ' . $count),
                'storage_waiting_weight' => DB::raw('storage_waiting_weight + ' . $weight),
            ];
        }

        if ($status == 2) {
            $updatedata = [
                'storage_waiting_pieces' => DB::raw('storage_waiting_pieces - ' . $count),
                'storage_waiting_weight' => DB::raw('storage_waiting_weight - ' . $weight),
                'current_pieces' => DB::raw('current_pieces + ' . $count),
                'current_weight' => DB::raw('current_weight + ' . $weight),
                'can_use_weight' => DB::raw('can_use_weight + ' . $weight),
                'can_use_pieces' => DB::raw('can_use_pieces + ' . $count),
            ];
        }

        if ($status == 3) {
            $updatedata = [
//                'storage_waiting_pieces' => DB::raw('storage_waiting_pieces - ' . $count),
//                'storage_waiting_weight' => DB::raw('storage_waiting_weight - ' . $weight),
                'current_pieces' => DB::raw('current_pieces + ' . $count),
                'current_weight' => DB::raw('current_weight + ' . $weight),
                'can_use_weight' => DB::raw('can_use_weight + ' . $weight),
                'can_use_pieces' => DB::raw('can_use_pieces + ' . $count),
            ];
        }
        try {

            StockStock::where(['cpid' => $cpid, 'id' => $stock_id])->update($updatedata);
            if ($stockinfo->archive_type == 1 && $length > 0) { //理计
                $subinfo = StockSub::where(['cpid' => $cpid, 'stock_id' => $stock_id, 'length' => $length])->first();

                if (!$subinfo) {
                    StockSub::create(['stock_id' => $stock_id, 'length' => $length, 'cpid' => $stockinfo->cpid]);
                }

                StockSub::where(['stock_id' => $stock_id, 'length' => $length])->update($updatedata);
            }
            //入库时计算平均重量avg_wight
            if ($stockinfo->archive_type == 2 && $status == 2) {
                if(mathfunc('add', $stockinfo->can_use_pieces, $count)>0){
                    StockStock::where(['id' => $stock_id, 'cpid' => $cpid])
                    ->update(['avg_wight' => mathfunc('div', mathfunc('add', mathfuncweight('mul', $stockinfo->can_use_weight, 10), $weight), mathfunc('add', $stockinfo->can_use_pieces, $count))]);

                }else{
                    StockStock::where(['id' => $stock_id, 'cpid' => $cpid])
                    ->update(['avg_wight' => 0]);

                }

           }
        } catch (\Exception $e) {
            Log::info($e->getMessage());
            throw new \Exception('库存更新失败');
        }
    }

    /**
     * 更改子库存,主库存不变
     */
    public static function doStockInSub($cpid, $stock_id, $count, $weight, $status = 1, $length = 0, $sp_num = '', $weight_unit = 0)
    {
        $stockinfo = StockStock::where(['cpid' => $cpid, 'id' => $stock_id])->first();
        if (!$stockinfo) {
            throw new \Exception('无效库存参数');
        }

        $updatedata = [];
        if ($status == 1) {
            $updatedata = [
                'storage_waiting_pieces' => DB::raw('storage_waiting_pieces + ' . $count),
                'storage_waiting_weight' => DB::raw('storage_waiting_weight + ' . $weight),
            ];
        }

        if ($status == 2) {
            $updatedata = [
                'storage_waiting_pieces' => DB::raw('storage_waiting_pieces - ' . $count),
                'storage_waiting_weight' => DB::raw('storage_waiting_weight - ' . $weight),
                'current_pieces' => DB::raw('current_pieces + ' . $count),
                'current_weight' => DB::raw('current_weight + ' . $weight),
                'can_use_weight' => DB::raw('can_use_weight + ' . $count),
                'can_use_pieces' => DB::raw('can_use_pieces + ' . $weight),
            ];
        }
        try {

            if ($stockinfo->archive_type == 1 && $length > 0) { //理计
                $subinfo = StockSub::where(['cpid' => $cpid, 'stock_id' => $stock_id, 'length' => $length, 'sp_num' => $sp_num])->first();

                if (!$subinfo) {
                    StockSub::create(['stock_id' => $stock_id, 'length' => $length, 'sp_num' => $sp_num, 'cpid' => $stockinfo->cpid, 'weight' => $weight_unit]);
                }

                StockSub::where(['stock_id' => $stock_id, 'length' => $length, 'sp_num' => $sp_num])->update($updatedata);
            }
        } catch (\Exception $e) {
            Log::info($e->getMessage());
            throw new \Exception('库存更新失败');
        }
    }

    /**
     * 库存出库
     * 减少总库存，以及子库存
     * $status,1待出(订单销售传正数，结算传负数)，2实际出
     */
    public static function doStockOut($cpid, $stock_id, $count, $weight, $status = 1, $length = 0)
    {

        $stockinfo = StockStock::where(['cpid' => $cpid, 'id' => $stock_id])->first();

        if (!$stockinfo) {
            throw new \Exception('无效库存参数');
        }
        if ($stockinfo->archive_type == 1 && $length > 0) {
            $subinfo = StockSub::where(['cpid' => $cpid, 'id' => $stock_id, 'length' => $length])->first();

            if (!$subinfo) {
                throw new \Exception('无效子库存参数');
            }
        }
        $updatedata = [];
        if ($status == 1) {
            $updatedata = [
                'locked_pieces' => DB::raw('locked_pieces + ' . $count),
                'locked_weight' => DB::raw('locked_weight + ' . $weight),
                'current_pieces' => DB::raw('current_pieces - ' . $count),
                'current_weight' => DB::raw('current_weight - ' . $weight),
                'can_use_weight' => DB::raw('can_use_weight - ' . $count),
                'can_use_pieces' => DB::raw('can_use_pieces - ' . $weight),
            ];
        }

        if ($status == 2) {
            $updatedata = [
                'locked_pieces' => DB::raw('locked_pieces - ' . $count),
                'locked_weight' => DB::raw('locked_weight - ' . $weight),
            ];
        }
        try {

            StockStock::where(['cpid' => $cpid, 'id' => $stock_id])->update($updatedata);
            if ($stockinfo->archive_type == 1 && $length > 0) {
                StockSub::where(['stock_id' => $stock_id, 'length' => $length])->update($updatedata);
            }
            //待出时计算平均重量avg_wight
            if ($stockinfo->archive_type == 2 && $status == 1) {
                StockStock::where(['cpid' => $cpid, 'id' => $stock_id])
                    ->update(['avg_wight' => mathfunc('div', mathfunc('sub', mathfuncweight('mul', $stockinfo->can_use_weight, 10), $weight), mathfunc('sub', $stockinfo->can_use_pieces, $count))]);
            }
        } catch (\Exception $e) {
            Log::info($e->getMessage());
            throw new \Exception('库存更新失败');
        }
    }

    /**
     * 库存管理，增加仓库，需要同步库存基础数据
     *
     * @param [type] $warehouse_id
     * @param [type] $cpid
     * @return void
     */
    public static function syncStockByWarehouse($warehouse_id, $infodata, $cpid)
    {
        $list = SteelArchive::where(['cpid' => $cpid])->get()->toArray();
        $data = [];
        foreach ($list as $val) {
            $data[] = [
                'cpid' => $cpid,
                'warehouse_id' => $warehouse_id,
                'warehouse_name' => $infodata['warehouse_name'],
                'steel_archive_id' => $val['id'],
                'archive_type' => $val['archive_type'],
                'material_id' => $val['material_id'],
                'archive_no' => $val['archive_no'],
                'archive_name' => $val['archive_name'],
                'archive_spec' => $val['archive_spec'],
                'archive_material' => $val['material_name'],
                'steel_factory_name' => $val['steel_factory_name'],
                'breed_name' => $val['breed_name'],
                'create_at' => time(),
                'update_at' => time(),
                'warehouse_type'=>$infodata['wtype'],
                'manger_id'=>$infodata['manger_id']
            ];
        }
        StockStock::insert($data);
        return;
    }

    /**
     * 库存管理，增加钢材编码，需要同步库存基础数据
     *
     * @param [type] $steel_archive_id
     * @param [type] $infodata 钢材档案基础数据
     * @param [type] $cpid
     * @return void
     */
    public static function syncStockBySteelArchive($steel_archive_id, $infodata, $cpid)
    {

        $list = WarehouseList::where(['cpid' => $cpid])->select(['id', 'warehouse_name','wtype','manger_id'])->get()->toArray();
        $data = [];
        foreach ($list as $val) {
            $data[] = [
                'cpid' => $cpid,
                'warehouse_id' => $val['id'],
                'warehouse_name' => $val['warehouse_name'],
                'steel_archive_id' => $steel_archive_id,
                'archive_type' => $infodata['archive_type'],
                'material_id' => $infodata['material_id'],
                'archive_no' => $infodata['archive_no'],
                'archive_name' => $infodata['archive_name'],
                'archive_spec' => $infodata['archive_spec'],
                'archive_material' => $infodata['material_name'],
                'steel_factory_name' => $infodata['steel_factory_name'],
                'breed_name' => $infodata['breed_name'],
                'create_at' => time(),
                'update_at' => time(),
                'warehouse_type'=>$val['wtype'],
                'manger_id'=>$val['manger_id']
            ];
        }
        StockStock::insert($data);
        return;
    }

    public static function syncStockBySteelArchiveUp($steel_archive_id, $infodata, $cpid)
    {

        $list = WarehouseList::where(['cpid' => $cpid])->select(['id', 'warehouse_name','wtype','manger_id'])->get()->toArray();
        foreach ($list as $val) {
            $data = [
                'archive_type' => $infodata['archive_type'],
                'archive_no' => $infodata['archive_no'],
                'material_id' => $infodata['material_id'],
                'archive_name' => $infodata['archive_name'],
                'archive_spec' => $infodata['archive_spec'],
                'archive_material' => $infodata['material_name'],
                'steel_factory_name' => $infodata['steel_factory_name'],
                'breed_name' => $infodata['breed_name'],
                'update_at' => time(),
            ];
            StockStock::where(['warehouse_id'=>$val['id'],'steel_archive_id'=>$steel_archive_id])->update($data);
        }
    }




    /**
     * 获取销售基价、加价
     */
    public static function getsaleprice($cpid)
    {

        $list = Saleprice::where(['cpid' => $cpid, 'is_del' => config('constants.is_del.no')])->get();
        if ($list) {
            $list = $list->toArray();
            $data = [];
            foreach ($list as $item) {
                $data[$item['type']][$item['name']]['name'] = $item['name'];
                $data[$item['type']][$item['name']]['op'] = $item['op'];
                $data[$item['type']][$item['name']]['amount'] = $item['amount'];
            }
            return $data;
        } else {
            return [];
        }
    }

    /**
     * 获取钢材加价
     */
    public static function getsteelprice($price_data, $base_price, $item)
    {
        // log::info('p:' . json_encode($price_data));
        // log::info('b:' . json_encode($base_price));
        // log::info('i:' . json_encode($item));
        //仓库
        if (!empty($price_data['warehouse_name'][$item['warehouse_name']])) {
            $warehouse_price = $price_data['warehouse_name'][$item['warehouse_name']]['amount'];
            $op = $price_data['warehouse_name'][$item['warehouse_name']]['op'];
            if ($op == 1) {
                $base_price = $base_price + $warehouse_price;
            } else {
                $base_price = $base_price - $warehouse_price;
            }
        }
        //钢厂
        if (!empty($price_data['steel_factory_name'][$item['steel_factory_name']])) {
            $steel_factory_price = $price_data['steel_factory_name'][$item['steel_factory_name']]['amount'];
            $op = $price_data['steel_factory_name'][$item['steel_factory_name']]['op'];
            if ($op == 1) {
                $base_price = $base_price + $steel_factory_price;
            } else {
                $base_price = $base_price - $steel_factory_price;
            }
        }
        //品种
        if (!empty($price_data['breed_name'][$item['breed_name']])) {
            $breed_price = $price_data['breed_name'][$item['breed_name']]['amount'];
            $op = $price_data['breed_name'][$item['breed_name']]['op'];
            if ($op == 1) {
                $base_price = $base_price + $breed_price;
            } else {
                $base_price = $base_price - $breed_price;
            }
        }
        //材质
        if (!empty($price_data['archive_material'][$item['archive_material']])) {
            $archive_material_price = $price_data['archive_material'][$item['archive_material']]['amount'];
            $op = $price_data['archive_material'][$item['archive_material']]['op'];
            if ($op == 1) {
                $base_price = $base_price + $archive_material_price;
            } else {
                $base_price = $base_price - $archive_material_price;
            }
        }

        if ($item['archive_type'] != 2) {
            $spec_arr = explode('*', $item['archive_spec']);

            if (!empty($spec_arr[0])) {
                if (!empty($price_data['specs_1'][$spec_arr[0]])) {
                    $specs_1_price = $price_data['specs_1'][$spec_arr[0]]['amount'];
                    $op = $price_data['specs_1'][$spec_arr[0]]['op'];
                    if ($op == 1) {
                        $base_price = $base_price + $specs_1_price;
                    } else {
                        $base_price = $base_price - $specs_1_price;
                    }
                }
            }

            if (!empty($spec_arr[1])) {
                if (!empty($price_data['specs_2'][$spec_arr[1]])) {
                    $specs_2_price = $price_data['specs_2'][$spec_arr[1]]['amount'];
                    $op = $price_data['specs_2'][$spec_arr[1]]['op'];
                    if ($op == 1) {
                        $base_price = $base_price + $specs_2_price;
                    } else {
                        $base_price = $base_price - $specs_2_price;
                    }
                }
            }

            if (!empty($spec_arr[2])) {
                if ($item['archive_type'] == 3) {
                    if (!empty($price_data['specs_3'][$spec_arr[2]])) {
                        $specs_3_price = $price_data['specs_3'][$spec_arr[2]]['amount'];
                        $op = $price_data['specs_3'][$spec_arr[2]]['op'];
                        if ($op == 1) {
                            $base_price = $base_price + $specs_3_price;
                        } else {
                            $base_price = $base_price - $specs_3_price;
                        }
                    }
                }
            }
        }

        //码单
        switch ($item['archive_type']) {
            case 1:
                $archive_type = '理计';
                break;
            case 2:
                $archive_type = '过磅';
                break;
            case 3:
                $archive_type = '定尺';
                break;
            case 4:
                $archive_type = '虚拟';
                break;
        }
        if (isset($price_data['archive_type'][$archive_type])) {
            $archive_type_price = $price_data['archive_type'][$archive_type]['amount'];
            $op = $price_data['archive_type'][$archive_type]['op'];
            if ($op == 1) {
                $base_price = $base_price + $archive_type_price;
            } else {
                $base_price = $base_price - $archive_type_price;
            }
        }
        return $base_price;
    }
}
